
#include "../iface/debug.h"
#include "SQLiteLockCounter.h"

/** Initialises the counter to one and enters the SQLite mutex lock.
 * 
 * @param idbmutex Database mutex pointer. */
SQLiteLockCounter::SQLiteLockCounter(sqlite3_mutex *idbmutex)
{
   counter = 1;
   dbmutex = idbmutex;
}

/** Gives an error if the mutex counter is non-zero and leaves the
 * SQLite mutex lock. */
SQLiteLockCounter::~SQLiteLockCounter()
{
   if (counter != 0) errprint("references %" APR_UINT64_T_FMT " and not zero", counter);
}

/** Increment the internal reference counter.
 * 
 * @return The new internal reference count. */
uint64_t SQLiteLockCounter::incrementReferenceCount()
{
   if (dbmutex)
   {
      if ((counter == 1) || (holdingthread != apr_os_thread_current()))
      {
         sqlite3_mutex_enter(dbmutex);
         holdingthread = apr_os_thread_current();
      }
   } else
      errprint("undefined behaviour possible: mutex is NULL");
   return ++counter;
}

/** Decrement the internal reference counter.
 * 
 * @return The new internal reference count. */
uint64_t SQLiteLockCounter::decrementReferenceCount()
{
   if (counter == 0)
      errprint("decrementing when zero");
   if (dbmutex)
   {
      if (holdingthread == apr_os_thread_current())
      {
         if (counter == 2) sqlite3_mutex_leave(dbmutex);
         return --counter;
      } else
      {
         errprint("wrong thread leaving mutex!");
      }
   } else
      errprint("undefined behaviour possible: mutex is NULL");
   return counter;
}
